package com.spicdt.edge.protocol.door.demo;

import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.spicdt.edge.protocol.door.demo.callback.dto.*;
import com.spicdt.edge.protocol.door.demo.conf.DoorConf;
import com.spicdt.edge.protocol.door.demo.handler.DoorCommandHandler;
import com.spicdt.edge.protocol.door.demo.model.dto.DeviceRecordQueryDTO;
import com.spicdt.edge.protocol.door.demo.model.dto.UserQueryDTO;
import com.spicdt.edge.protocol.door.demo.model.po.Staff;
import com.spicdt.edge.protocol.door.demo.model.po.StaffDoorAccess;
import com.spicdt.edge.protocol.door.demo.service.DoorBaseService;
import com.spicdt.edge.protocol.door.demo.service.DoorBaseServiceImpl;
import com.spicdt.iedge.psdk.EdgeDataService;
import com.spicdt.iedge.psdk.EdgeService;
import com.spicdt.iedge.psdk.ProtocolService;
import com.spicdt.iedge.psdk.annotation.EnableSpringWebContext;
import com.spicdt.iedge.psdk.data.CommandSubscription;
import com.spicdt.iedge.psdk.data.ConfigurationException;
import com.spicdt.iedge.psdk.data.DeviceAlarm;
import com.spicdt.iedge.psdk.data.Response;
import com.spicdt.iedge.psdk.device.DeviceInfo;
import com.spicdt.iedge.psdk.meta.*;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;

import java.time.Instant;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.spicdt.edge.protocol.door.demo.callback.dto.OpType.ADD;

/**
 * 智慧门禁协议接入
 */
@Slf4j
@EnableSpringWebContext
public class DoorProtocolService implements ProtocolService {

    private EdgeService edgeService;

    @Getter
    private EdgeDataService edgeDataService;



    private Configuration configuration;


    private StateEnum stateEnum;


    private DoorCommandHandler rpcProcessor;


    private DoorBaseService doorBaseService;

    // 定时任务线程池
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

    /**
     * 存储平台设备编码（Platform Device CODE）到南向设备编码（Southbound Device CODE）的映射关系。
     */
    public Map<String, String> platformToDeviceCodeMap = new HashMap<>();

    /**
     * 南向设备编码（Southbound Device CODE）到平台设备ID（Platform Device CODE）的映射。
     * Key: 南向设备SN（如永鑫协议设备编号）
     * Value: 平台侧统一设备ID
     */
    public Map<String, String> southboundToPlatformDeviceMap = new HashMap<>();

    /**
     * 存储设备编码（Device CODE）到设备信息（DeviceInfo）的映射关系。
     * Key: 设备唯一标识（如平台侧设备CODE）
     * Value: 对应的设备详细信息（DeviceInfo）
     */
    public static Map<String, DeviceInfo> deviceCodeToInfoMap = new HashMap<>();

    private boolean deviceOnlined = false;


    private DoorConf currentDoorConf;

    // 创建第一个线程池，用于执行的任务
    ScheduledExecutorService pool1 = Executors.newScheduledThreadPool(2);

    // 创建第二个线程池，用于门禁事件获取任务
    ScheduledExecutorService pool2 = Executors.newScheduledThreadPool(2);

    // 创建第三个线程池，用于处理token
    private final ScheduledExecutorService pool3 = Executors.newSingleThreadScheduledExecutor();

    // 创建第四个线程池，用于处理token
    private final ScheduledExecutorService pool4 = Executors.newSingleThreadScheduledExecutor();


    public DoorProtocolService(EdgeService edgeService) {
        this.edgeService = edgeService;
    }

    @Override
    public Configuration getConfiguration() {
        return configuration;
    }


    /**
     * 测试门禁设备连接性
     *
     * @param configuration 配置信息
     * @throws ConfigurationException 配置验证或连接失败时抛出
     */
    @Override
    public void test(Configuration configuration) throws ConfigurationException {
        String channelId = configuration.getChannelId();
        log.info("[Channel:{}] 开始执行门禁协议测试", channelId);
        log.info("getConfiguration",configuration.getConfiguration());
        log.info("getConfigureType",configuration.getConfigureType().getValue());
        log.info("getDataSourceName",configuration.getDataSourceName());

        DoorBaseServiceImpl doorService = null;

        try {
            // 1. 处理配置
            DoorConf doorConf = processConfiguration(configuration);
            if (doorConf == null) {
                throw new ConfigurationException("配置解析失败，doorConf 为 null");
            }

            // 2. 初始化服务
            doorService = new DoorBaseServiceImpl(doorConf);

            doorService.getToken(doorConf);

            // 3. 执行心跳检测
            Response heartbeatResponse = doorService.heartbeat();

            // 4. 验证响应
            if (heartbeatResponse == null) {
                throw new ConfigurationException("心跳检测失败：响应为空");
            }

            if (!"200".equals(heartbeatResponse.getCode())) {
                String errorMsg = String.format("心跳检测失败，错误码：%s，错误信息：%s",
                    heartbeatResponse.getCode(), heartbeatResponse.getMsg());
                throw new ConfigurationException(errorMsg);
            }
//            this.doorBaseService = new DoorBaseServiceImpl(doorConf);
//            TestInitToken(doorConf);
//            updateStaffInfo();
//            updateStaffAuth();
            log.info("[Channel:{}] 门禁协议测试成功", channelId);

        } catch (ConfigurationException e) {
            // 已知配置异常直接抛出
            log.error("[Channel:{}] 配置测试失败: {}", channelId, e.getMessage(), e);
            throw e;
        } catch (Exception e) {
            // 未知异常包装成配置异常
            String errorMsg = String.format("门禁协议测试异常：%s", e.getMessage());
            log.error("[Channel:{}] %s", channelId, errorMsg, e);
            throw new ConfigurationException(errorMsg, e);
        }
    }

    private void updateStaffAuth() {
        UserQueryDTO userQueryDTO = new UserQueryDTO();
        userQueryDTO.setDataType("simple-doorAccess");
        Response staffInfo = doorBaseService.getStaffInfo(userQueryDTO);

        Object object = JSONUtil.parseObj(staffInfo.getData()).get("staff");

        List<Staff> staff = JSONUtil.parseArray(object).toList(Staff.class);


        List<PersonAuthorizeDto> personAuthorizeDtoList = new ArrayList<>();
        staff.forEach(e->{
            PersonAuthorizeDto personAuthorizeDto = new PersonAuthorizeDto();
            personAuthorizeDto.setPersonId(e.getStaffID());
            personAuthorizeDto.setPhone(e.getMobile());
            PersonAuthorizeDto.Authority authority = new PersonAuthorizeDto.Authority();

            List<StaffDoorAccess> staffDoorAccess = e.getStaffDoorAccess();

            List<PersonAuthorizeDto.DeviceInfo> deviceInfoList=new ArrayList<>();
            staffDoorAccess.forEach(e1->{
                        PersonAuthorizeDto.DeviceInfo deviceInfo = new PersonAuthorizeDto.DeviceInfo();
                        deviceInfo.setDeviceCode(e1.getControllerID() + "}--}" + e1.getDoorID());
                        deviceInfo.setDeviceName(e1.getDoorName());
                        deviceInfoList.add(deviceInfo);
                    });
            authority.setDeviceList(deviceInfoList);
            List<PersonAuthorizeDto.Authority> authorityList = Collections.singletonList(authority);
            personAuthorizeDto.setAuthorityList(authorityList);
            personAuthorizeDtoList.add(personAuthorizeDto);
        });
//        log.info("}}}}}}}}}}}}}}}}}}}}}"+personAuthorizeDtoList.toString());



//        List<AuthorizeInfo> pushAuthorityList = personAuthorizeDto.transfer();
//        log.info("[中控回调]，推送用户授权数据,sourceId:{}，pushAuthorityList:{}", configuration.getChannelId(), JSONUtil.toJsonStr(pushAuthorityList));
//        edgeDataService.publishEdgeDataByType(configuration.getChannelId(), pushAuthorityList, EdgeDataType.authSync);

    }

    @Override
    public void init(Configuration configuration) throws Exception {
        try {
            this.configuration = configuration;
            this.edgeDataService = edgeService.getEdgeCapability(EdgeDataService.class);
            log.info("[鑫业门禁] [{}]进入智慧门禁init 方法,openapi版本,channelId:[{}]", configuration, configuration.getChannelId());
            //===1,获取连接信息
            DoorConf doorConf = processConfiguration(configuration);
            this.currentDoorConf = doorConf;
            //===2,初始化门禁系统连接service
            this.doorBaseService = new DoorBaseServiceImpl(doorConf);
            initToken();
            this.doorBaseService.setCurrentToken(currentDoorConf.getCurrentToken());
            /*获取边平台在连接上配置的南向设备数据并缓存*/
            initDeviceAndPoint(configuration.getChannelId());

            //===3,订阅设备RPC指令
            subscribeDeviceOnCommand(configuration.getChannelId());

            //===4,获取设备状态信息
            // 在线程池1中执行定时任务：每5秒打印一次当前时间
            pool1.scheduleAtFixedRate(this::checkDevicesOnline,0, 400, TimeUnit.SECONDS);


            /*定时获取门禁系统出入事件*/
            pool2.scheduleAtFixedRate(this::getDoorEvent,10, 600, TimeUnit.SECONDS);

            /**
             * 定时向北向更新人员信息
             */
            pool4.scheduleAtFixedRate(this::updateStaffInfo,0, 600, TimeUnit.SECONDS);

            log.info("\n\n\n\n\n[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[\n\n\n\n\n");
            updateStaffAuth();
        } catch (Exception e) {
            log.error("[鑫业 door] [{}]智慧门禁init 方法异常,异常信息:[{}]", configuration, e.getMessage());
        }
    }

    private void updateStaffInfo() {
        Response response = doorBaseService.getStaffInfo(new UserQueryDTO());

        JSONObject responseData = JSON.parseObject(response.getData().toString());
        List<Staff> staff = JSONUtil.parseArray(responseData.get("staff")).toList(Staff.class);
        List<PersonInfoDto> collect = staff.stream().map(this::transformToPersonInfoDto).collect(Collectors.toList());


        List<PersonInfo> dataList = collect.stream()
                    .map(PersonInfoDto::transfer)
                    .collect(Collectors.toList());
        log.info("[中控回调]，推送用户数据,sourceId:{}，dataList:{}", configuration.getChannelId(), JSONUtil.toJsonStr(dataList));
        edgeDataService.publishEdgeDataByType(configuration.getChannelId(), dataList, EdgeDataType.person);

    }

    public PersonInfoDto transformToPersonInfoDto(Staff staff){
        PersonInfoDto personInfoDto = new PersonInfoDto();
        personInfoDto.setPersonId(staff.getStaffID());
        personInfoDto.setPersonName(staff.getStaffName());
        personInfoDto.setPhone(staff.getMobile());
        return personInfoDto;
    }

    @Override
    public void update(Configuration configuration) throws Exception {
        try {
            destroy();
            init(configuration);
        } catch (Exception e) {
            log.error("智慧门禁init error", e);
            throw new Exception(e);
        }
    }

    @Override
    public void destroy() throws Exception {
        pool1.shutdownNow();
        pool2.shutdownNow();
        pool3.shutdownNow();
        pool4.shutdownNow();
        setState(StateEnum.offline);
        if (this.rpcProcessor != null) {
            this.rpcProcessor = null;
        }
        if (!deviceOnlined) {
            deviceOnlined = false;
        }
        //取消订阅子设备
        if (doorBaseService != null) {
            doorBaseService = null;
        }
    }

    /**
     * 初始化指定通道下的设备及其映射关系。
     *
     * @param channelId 通道ID（通常对应协议配置）
     */
    public void initDeviceAndPoint(String channelId) {
        log.info("[Channel:{}] 开始初始化设备与点表映射", channelId);

        List<DeviceInfo> deviceInfos = edgeService.deviceList(channelId);
        if (CollectionUtils.isEmpty(deviceInfos)) {
            log.warn("[Channel:{}] 未找到关联设备", channelId);
            return;
        }

        for (DeviceInfo deviceInfo : deviceInfos) {
            String deviceKey = deviceInfo.getDeviceKey();
            String southboundDeviceCode = getSouthboundDeviceCode(deviceInfo);

            if (StringUtils.isBlank(southboundDeviceCode)) {
                log.warn("[Channel:{}] 设备 {} 缺少南向编码信息", channelId, deviceKey);
                continue;
            }

            // 构建双向映射
            southboundToPlatformDeviceMap.putIfAbsent(southboundDeviceCode, deviceKey);
            platformToDeviceCodeMap.putIfAbsent(deviceKey, southboundDeviceCode);
            deviceCodeToInfoMap.put(deviceKey, deviceInfo);
        }

        // 调试用的日志输出（上线前建议关闭或调整为 debug）
        log.debug("southboundToPlatformDeviceMap: {}", JSONUtil.toJsonStr(southboundToPlatformDeviceMap));
        log.debug("platformToDeviceCodeMap: {}", JSONUtil.toJsonStr(platformToDeviceCodeMap));
        log.debug("deviceCodeToInfoMap: {}", JSONUtil.toJsonStr(deviceCodeToInfoMap));
    }

    /**
     * 获取设备对应的南向编码（优先 srcDeviceCode，其次 srcDeviceName）
     */
    private String getSouthboundDeviceCode(DeviceInfo deviceInfo) {
        String code = deviceInfo.getMappingProperty("srcDeviceCode");
        if (StringUtils.isBlank(code)) {
            code = deviceInfo.getMappingProperty("srcDeviceName");
        }
        return code;
    }

    /**
     * 处理并解析鑫业门禁协议的配置信息。
     *
     * @param configuration 原始配置对象
     * @return 解析后的 DoorConf 配置对象
     * @throws Exception 配置解析失败时抛出异常
     */
    public DoorConf processConfiguration(Configuration configuration) throws Exception {

        DoorConf doorConfig;
        String channelId = configuration.getChannelId();

        log.info("[Channel:{}] Initializing 鑫业 door service. Configuration:{}", channelId, configuration);

        try {
            ObjectMapper objectMapper = new ObjectMapper();



            if (ConfigureType.JSON.equals(configuration.getConfigureType())) {
                // 从 JSON 字符串解析配置
                doorConfig = objectMapper.treeToValue(
                    objectMapper.readTree(configuration.getConfiguration()),
                    DoorConf.class
                );
                log.info("====================类型测试666=================");
                log.info(doorConfig.toString());
            } else {
                // 从资源文件加载配置
                doorConfig = objectMapper.readValue(
                    this.getClass().getClassLoader().getResourceAsStream(configuration.getConfiguration()),
                    DoorConf.class
                );
            }

            log.info("[Extension][鑫业 door][{}] 配置加载成功", channelId);

            // 设置当前配置
            this.currentDoorConf = doorConfig;

            return doorConfig;

        } catch (Exception e) {
            String errorMsg = String.format("[Channel:%s] 鑫业 door service 配置加载失败: %s", channelId, e.getMessage());
            log.error(errorMsg, e);
            edgeService.channelError(channelId, e);
            throw new Exception(errorMsg, e);
        }
    }
    @Override
    public StateEnum getState() {
        return this.stateEnum;
    }

    @Override
    public CompletableFuture<Boolean> setState(StateEnum stateEnum) {
        this.stateEnum = stateEnum;
        return CompletableFuture.completedFuture(true);
    }

    @Override
    public void restart() {
        try {
            update(configuration);
        } catch (Throwable e) {
            log.error("[鑫业]门禁服务重启检出错.", e);
            throw new RuntimeException(e);
        }
    }

    /**
     * 订阅设备指令
     */
    private void subscribeDeviceOnCommand(String sourceId) {
        //1,订阅子设备
        log.info("[{}]订阅设备RPC指令开始", sourceId);
        this.rpcProcessor = new DoorCommandHandler(doorBaseService, edgeService, currentDoorConf,platformToDeviceCodeMap);
        List<DeviceInfo> deviceInfos = edgeService.deviceList(sourceId);
        if (CollectionUtils.isEmpty(deviceInfos)) {
            log.info("[{}]订阅设备RPC指令失败,无设备数据", sourceId);
            return;
        }
        for (DeviceInfo deviceInfo : deviceInfos) {
            try {
                edgeService.subscribe(new CommandSubscription(configuration.getChannelId(), deviceInfo.getDeviceKey(), this.rpcProcessor));
                log.info("[{}] subscribe success device:{} ", configuration.getChannelId(), deviceInfo.getDeviceKey());

            } catch (Exception e) {
                log.error("[{}] subscribe error device:{} msg:{}", configuration.getChannelId(), deviceInfo.getDeviceKey(), e.getMessage(), e);
            }
        }
    }

    public void processService(DoorConf config, Configuration configuration) {
        try {


            log.info("[Extension][ZKTecho][{}]  连接协议启动成功", configuration.getChannelId());
        } catch (Exception e) {
            log.error("[{}] Door service initialization failed", configuration.getChannelId(), e);
            edgeService.channelError(configuration.getChannelId(), e);
            throw e;
        }
    }


    /**
     * 定期检查设备在线状态并同步到平台
     */
    private void checkDevicesOnline() {
        // 1. 检查当前通道状态
        if (!getState().equals(StateEnum.online)) {
            return;
        }

        String channelId = configuration.getChannelId();
        log.info("[Channel:{}] 开始设备在线状态检查", channelId);

        try {
            // 2. 获取设备列表
            List<DeviceInfo> deviceInfos = edgeService.deviceList(channelId);
            if (CollectionUtils.isEmpty(deviceInfos)) {
                log.warn("[Channel:{}] 未找到关联设备", channelId);
                return;
            }

            // 3. 获取全量设备状态
            Map<String, JSONArray> deviceStatusMap = fetchAllDeviceStatus();

            // 4. 更新设备状态
            updateDeviceOnlineStatus(deviceInfos, deviceStatusMap);

        } catch (Exception e) {
            log.error("[Channel:{}] 设备状态检查异常: {}", channelId, e.getMessage(), e);
        }
    }

    /**
     * 获取所有设备状态并构建映射
     */
    private Map<String, JSONArray> fetchAllDeviceStatus() throws Exception {
        Map<String, JSONArray> statusMap = new HashMap<>();

        // 1. 查询设备状态
        DeviceRecordQueryDTO deviceRecordQueryDTO = new DeviceRecordQueryDTO();
        deviceRecordQueryDTO.setDataType("highest");
        Response response = doorBaseService.allDoorState(deviceRecordQueryDTO);
        if (!response.isSuccess() || response.getData() == null) {
            log.warn("设备状态查询失败，响应无效");
            return statusMap;
        }

        try {
            // 2. 解析响应数据
            JSONObject root = JSON.parseObject(response.getData().toString());
            JSONArray hardwareList = root.getJSONArray("hardware");

            // 3. 构建设备状态映射
            for (int i = 0; i < hardwareList.size(); i++) {
                JSONObject hardware = hardwareList.getJSONObject(i);
                String doorID = hardware.getString("doorID");
                String controllerID = hardware.getString("controllerID");
                JSONArray deviceStatusArray = hardware.getJSONArray("deviceStatus");

                if (StringUtils.isNotBlank(doorID)&&StringUtils.isNotBlank(controllerID) && deviceStatusArray != null) {
                    statusMap.put(controllerID+"}--}"+doorID, deviceStatusArray);
                }
            }

        } catch (JSONException e) {
            log.error("JSON解析失败: {}", e.getMessage(), e);
            throw new Exception("设备状态数据解析失败", e);
        }

        return statusMap;
    }

    /**
     * 根据状态映射更新设备在线状态
     */
    private void updateDeviceOnlineStatus(List<DeviceInfo> deviceInfos, Map<String, JSONArray> statusMap) {
        // 缓存配置项
//        String onlineStatusName = currentDoorConf.getOnlineName();
        String offlineStatusName = currentDoorConf.getOfflineName();
        String offlineStatusValue = currentDoorConf.getOfflineValue();

        log.info("++++++++++++++开始更新状态"+offlineStatusName+"--------------"+offlineStatusValue);
        deviceInfos.forEach(deviceInfo -> {
            String srcDeviceCode = deviceInfo.getMappingProperty("srcDeviceCode");
            log.info("srcDeviceCode:{}",srcDeviceCode);
            if (StringUtils.isBlank(srcDeviceCode)) {
                log.info("设备 {} 缺少南向编码", deviceInfo.getDeviceKey());
                return;
            }

//            edgeService.deviceOffline(deviceInfo.getDeviceKey());

            JSONArray deviceStatusArray = statusMap.get(srcDeviceCode);
            if (deviceStatusArray == null || deviceStatusArray.isEmpty()) {
                log.info("未找到设备 {} 的状态信息", srcDeviceCode);
                return;
            }

            for (int j = 0; j < deviceStatusArray.size(); j++) {
                JSONObject status = deviceStatusArray.getJSONObject(j);
                String statusName = status.getString("statusName");
                String statusValue = status.getString("statusValue");
                if (offlineStatusName.equals(statusName)) {
                    log.info("名称一致");
                    if (!offlineStatusValue.equals(statusValue)) {
                        edgeService.deviceOnline(deviceInfo.getDeviceKey());
                        log.info("\n\n\n\n\n[[[[[[[[[[[[[[[[[[[[[[[[[[[\n\n\n\n\n");
                        log.info("设备 {} 在线", deviceInfo.getDeviceKey());
                        log.info(statusName+"))))))))))))"+statusValue);
                        return;
                    }
                }
            }
            log.info("设备 {} 离线", deviceInfo.getDeviceKey());
            edgeService.deviceOffline(deviceInfo.getDeviceKey());

        });
    }

    /**
     * 定时获取门禁事件并推送告警
     */
    private void getDoorEvent() {
        Date now = new Date();
        String queryStartTime = formatQueryTime(DateUtil.offsetSecond(now, -currentDoorConf.getEventInterval()));
        String queryEndTime = formatQueryTime(now);

        log.debug("[Channel:{}] 开始获取门禁事件 - 时间范围: {} ~ {}",
            configuration.getChannelId(), queryStartTime, queryEndTime);

        int pageSize = 50;
        int pageNo = 1;
//        boolean hasMoreData;
        boolean hasMoreData=false;

        do {
            try {
                // 1. 获取事件数据
                Response response = doorBaseService.getDoorEventList(queryStartTime, queryEndTime, pageNo, pageSize);

                if (!response.isSuccess() || response.getData() == null) {
                    log.warn("[Channel:{}] 事件查询失败: {}",
                        configuration.getChannelId(), response.getMsg());
                    break;
                }

                // 2. 解析事件数据和分页信息
                JSONObject responseData = JSON.parseObject(response.getData().toString());
                JSONArray ioDataArray = responseData.getJSONArray("ioData");
                int totalPage = responseData.getIntValue("totalPage");

                if (ioDataArray == null || ioDataArray.isEmpty()) {
                    log.debug("[Channel:{}] 未查询到新事件", configuration.getChannelId());
                    break;
                }

                // 3. 处理事件数据
                processEventData(ioDataArray);

                //todo 需要进行修改

                // 4. 判断是否还有更多数据 - 根据当前页和总页数判断
//                hasMoreData = pageNo < totalPage;
//                if (hasMoreData) {
//                    pageNo++;
//                    log.debug("[Channel:{}] 继续获取下一页事件数据，当前页:{}, 总页数:{}",
//                        configuration.getChannelId(), pageNo, totalPage);
//                }

            } catch (JSONException e) {
                log.error("[Channel:{}] JSON解析失败: {}",
                    configuration.getChannelId(), e.getMessage(), e);
                break;
            } catch (Exception e) {
                log.error("[Channel:{}] 获取门禁事件异常: {}",
                    configuration.getChannelId(), e.getMessage(), e);
                break;
            }

        } while (hasMoreData);
    }

    /**
     * 格式化查询时间（yyyyMMddHHmm）
     */
    private String formatQueryTime(Date date) {
        return DateUtil.format(date, "yyyyMMddHHmm");
    }

    /**
     * 解析响应数据中的事件列表
     */
    private JSONArray parseEventData(String rawData) throws JSONException {
        JSONObject responseJson = JSON.parseObject(rawData);
        return responseJson.getJSONArray("ioData");

    }

    /**
     * 处理单个事件数据
     */
    private void processEventData(JSONArray ioDataArray) {
        for (int i = 0; i < ioDataArray.size(); i++) {
            JSONObject ioData = ioDataArray.getJSONObject(i);

            try {
                // 提取基础字段
                String controllerID = ioData.getString("controllerID").trim();
                String deviceId = ioData.getString("doorID").trim();
                String deviceName = ioData.getString("doorName").trim();
                String eventName = ioData.getString("eventName").trim();
                String recordTime = ioData.getString("recordTime").trim();
                String eventCode = ioData.getString("eventCode").trim();



                //构建南向编码
                String southboundDeviceCode = controllerID + "}--}" + deviceId;
                log.info("南向编码为"+southboundDeviceCode);

                // 获取平台设备Key
                if (StringUtils.isNotBlank(deviceId) && southboundToPlatformDeviceMap.containsKey(southboundDeviceCode)) {
                    // 构建告警对象
                    DeviceAlarm deviceAlarm = buildDeviceAlarm(ioData,eventName, eventCode, recordTime);

                    String deviceKey = southboundToPlatformDeviceMap.get(southboundDeviceCode);
                    log.info("设备Key为"+deviceKey);

                    edgeService.deviceAlarmUpdate(deviceKey, Arrays.asList(deviceAlarm));
                    log.info("开始更新事件"+eventName+"====="+eventCode+"====="+recordTime);
                }
//                else {
//                    log.warn("[Channel:{}][Device:{}] 未找到对应的南向设备配置",
//                        configuration.getChannelId(), deviceName);
//                }

            } catch (Exception e) {
                log.error("[Channel:{}] 事件处理失败: {}",
                    configuration.getChannelId(), ioData.toJSONString(), e);
            }
        }
    }

    /**
     * 构建设备告警对象
     */
    private DeviceAlarm buildDeviceAlarm(JSONObject ioData, String eventName, String eventCode, String recordTime) {
        long timestamp = parseEventTime(recordTime);

        DeviceAlarm deviceAlarm = new DeviceAlarm();
        deviceAlarm.setStatus(AlarmStatus.ACTIVE_ACK);
        deviceAlarm.setType("正常开门");
        deviceAlarm.setLevel(AlarmLevel.WARNING);
        deviceAlarm.setAlarmCode(eventCode);
        deviceAlarm.setStartTs(timestamp);
        deviceAlarm.setClearTs(timestamp);
        deviceAlarm.setCreatedTime(timestamp);


//        AlarmDetail detail = new AlarmDetail();
//        detail.setContent(eventName);
//        detail.setAlarmType(deviceAlarm.getType());
//        detail.setTimestamp(timestamp);
//        detail.setAlarmLevel(AlarmLevel.WARNING);
//        detail.setDeviceId(eventCode); // 根据实际情况调整
//        detail.setDeviceName(eventName); // 根据实际情况调整

        deviceAlarm.setDetails(JSON.toJSONString(ioData));
        return deviceAlarm;
    }

    /**
     * 解析事件时间
     */
    private long parseEventTime(String timeStr) {
        return DateUtil.parse(timeStr, "yyyyMMddHHmmss").getTime();
    }


    /**
     * 初始化 Token 并启动定时任务
     */
    private void initToken() {
        try{
        log.info("开始初始化 Token...");

        Response response = doorBaseService.getToken(currentDoorConf);
        if (response.isSuccess()) {
            Object data = response.getData();
            if (data != null) {
                String[] split = data.toString().split("}--}");
                currentDoorConf.setCurrentToken (split[0]);
                log.info("================token===============",currentDoorConf.getCurrentToken());
                currentDoorConf.setTokenExpirationTime (Long.valueOf(split[1])); ;

                log.info("Token 初始化成功: {}", currentDoorConf.getCurrentToken());
                log.debug("Token 过期时间戳: {}", currentDoorConf.getTokenExpirationTime());

                // 启动定时任务
                pool3.scheduleAtFixedRate(this::checkAndRefreshToken, 0, 600, TimeUnit.SECONDS);
            } else {
                log.error("初始化 Token 失败，响应数据为空");
                setState(StateEnum.offline);
                throw new RuntimeException("初始化 Token 失败，响应数据为空");
            }
        } else {
            log.error("初始化 Token 失败：{}", response.getMsg());
            setState(StateEnum.offline);
            throw new RuntimeException("初始化 Token 失败：" + response.getMsg());

        }
        setState(StateEnum.online);
        } catch (Exception e) {
            log.error("[Channel:{}] Token 数据转换失败: {}",
                configuration.getChannelId(), e.getMessage(), e);
            setState(StateEnum.offline);
        }
    }

    /**
     * 初始化 Token 并启动定时任务(测试)
     */
    private void TestInitToken(DoorConf doorConf) {
        try{
        log.info("开始初始化 Token..."+doorConf);
        Response response = doorBaseService.getToken(doorConf);
        log.info("测试token初始化"+response.toString());
        if (response.isSuccess()) {
            Object data = response.getData();
            if (data != null) {
                String[] split = data.toString().split("}--}");
                currentDoorConf.setCurrentToken (split[0]);
                currentDoorConf.setTokenExpirationTime (Long.valueOf(split[1])); ;
            }
        }
        } catch (Exception e) {
            log.error("测试token初始化失败"+e.getMessage());
        }
    }

    /**
     * 检查 Token 是否需要刷新
     */
    private void checkAndRefreshToken() {
        log.debug("检查 Token 是否需要刷新...");

        if (currentDoorConf.getTokenExpirationTime() == null) {
            log.warn("未设置 Token 过期时间，跳过刷新");
            return;
        }

        long currentTime = Instant.now().getEpochSecond();

        log.info("当前时间:"+currentTime);
        log.info("过期时间:"+currentDoorConf.getTokenExpirationTime());
        log.info("过期时间-当前时间:{}",currentDoorConf.getTokenExpirationTime()-currentTime);

        log.debug("当前时间戳: {}, Token 过期时间戳: {}", currentTime, currentDoorConf.getTokenExpirationTime());

        if (currentDoorConf.getTokenExpirationTime() - currentTime <= 60) {
            log.info("Token 即将过期，准备刷新...");
            refreshToken();
        } else {
            log.debug("Token 仍有效，无需刷新");

        }
    }

    /**
     * 刷新 Token
     */
    private void refreshToken() {
        try{
        log.info("开始刷新 Token..."+doorBaseService);
        if (Objects.isNull(doorBaseService)){
            log.info("================doorBaseService is null================");
        }else {
            log.info("================doorBaseService is not null================");
            log.info("===================="+currentDoorConf.toString()+"=================");
        }

        Response response = this.doorBaseService.getToken(currentDoorConf);
        if (response.isSuccess()) {
            Object data = response.getData();
            if (data != null) {
                String[] split = data.toString().split("}--}");
                currentDoorConf.setCurrentToken (split[0]);
                log.info("================token===============",data);
                currentDoorConf.setTokenExpirationTime (Long.valueOf(split[1])); ;


                log.info("Token 刷新成功: {}", currentDoorConf.getCurrentToken());
                log.debug("Token 过期时间戳: {}", currentDoorConf.getTokenExpirationTime());
                setState(StateEnum.online);

            } else {
                log.error("刷新 Token 失败，响应数据为空");
                setState(StateEnum.offline);
            }
        } else {
            setState(StateEnum.offline);
            log.error("刷新 Token 失败：{}", response.getMsg());
        }
    } catch (Exception e) {
        log.error("[Channel:{}] Token 数据转换失败: {}",
            configuration.getChannelId(), e.getMessage(), e);
            setState(StateEnum.offline);
    }
    }

}
